package com.linjiahao.nettyOne.handler.Impl;

import com.linjiahao.servicebase.exception.ErrorMessage;
import com.linjiahao.nettyOne.constant.HandlerServiceName;
import com.linjiahao.nettyOne.handler.AbstractHandle;
import com.linjiahao.nettyOne.handler.ChannelHandlerPool;
import com.linjiahao.nettyOne.handler.HandlerServiceFactory;
import com.linjiahao.servicebase.common.RedisService;
import com.linjiahao.servicebase.util.JWTUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

/**
 * @ClassName AuthHttpHanlder
 * @Description: 鉴权处理逻辑
 * @Author linjiahao
 * @Date 28/12/2021
 **/
@Service
@Slf4j
public class AuthHttpHandlerImpl implements AbstractHandle, InitializingBean {

    private WebSocketServerHandshaker handshaker;

    @Resource
    private RedisService redisService;

    @Value("${netty.url}")
    private String webSocketUrl;

    public final String token = "token";

    @Override
    public String getServiceTypeName() {
        return HandlerServiceName.AUTH_HANDLER.getName();
    }

    @Override
    public Object handlerWebsocket(ChannelHandlerContext ctx, Object message) {
        FullHttpRequest request = (FullHttpRequest) message;
        String uri =request.getUri();
        log.info("连接前鉴权的uri:{}",uri);
        List<String> list = Arrays.asList(uri.split("\\?"));
        Boolean isHaveToken = list.stream().filter(m -> m.contains(token)).findFirst().isPresent();
        if(!isHaveToken){
            log.info("鉴权不通过，token字段缺失,用户未登录");
            ctx.channel().writeAndFlush(new TextWebSocketFrame(ErrorMessage.USER_NOT_LOGIN.toString()));
            ctx.close();
            return "";
        }
        List<String> params = Arrays.asList(list.get(1).split("&"));
        String authToken = params.stream().filter(m -> m.contains(token)).findFirst().get();
        String tokenValue = authToken.split("=")[1];
        String userId = String.valueOf(JWTUtil.getUserId(tokenValue));
        log.info("channel的id为：{},用户id为：{}",ctx.channel().id(),userId);
        redisService.hset(ChannelHandlerPool.channelUserKey, userId, ctx.channel().id());
        WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
                webSocketUrl, "WebSocket", false,65536 * 10);
        handshaker = wsFactory.newHandshaker(request);
        if (handshaker == null) {
            WebSocketServerHandshakerFactory
                    .sendUnsupportedVersionResponse(ctx.channel());
        } else {
            handshaker.handshake(ctx.channel(), request);
        }
        //获取是否有离线消息
        log.info("鉴权通过，查询是否有离线消息，用户为：{}",userId);
        Object userMessage = redisService.hget(ChannelHandlerPool.userMessageKey, userId);
        log.info("鉴权通过，查询是否有离线消息，用户为：{}，离线消息：{}",userId,userMessage);
        if(userMessage != null){
            ctx.channel().writeAndFlush(new TextWebSocketFrame(userMessage.toString()));
            redisService.hdel(ChannelHandlerPool.userMessageKey,userId);
        }
        return userId;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        HandlerServiceFactory.register(getServiceTypeName(),this);
    }


}
